/**
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 */
import { DateObject, Period } from "../types/common";
import { UseDisableDate } from "./types";
import { useCompare } from "./use-compare";
import { useDate } from "./use-date";
import { useNumber } from "./use-number";

export function useDisableDate(
    minYear: number,
    maxYear: number,
    disableSince: DateObject,
    disableUntil: DateObject,
    disableDates: DateObject[],
    disablePeriod: Period[],
    disableWeekends: boolean,
    disableWeekdays: string[]
): UseDisableDate {

    const { getTimeInMilliseconds, getWeekdayIndex } = useDate();
    const { isInitializedDate } = useCompare();
    const { getDayNumber } = useNumber();

    function isDisabledDate(date: DateObject): boolean {
        if ((date.year && date.year < minYear && date.month === 12) || (date.year && date.year > maxYear && date.month === 1)) {
            return true;
        }
        const dateMs: number = getTimeInMilliseconds(date);
        if (isInitializedDate(disableUntil) && (dateMs + 24 * 60 * 60 * 1000 - 1) < getTimeInMilliseconds(disableUntil)) {
            return true;
        }
        if (isInitializedDate(disableSince) && dateMs > getTimeInMilliseconds(disableSince)) {
            return true;
        }

        if (disableWeekends) {
            const dayNbr = getDayNumber(date);
            if (dayNbr === 0 || dayNbr === 6) {
                return true;
            }
        }

        const dn = getDayNumber(date);
        if (disableWeekdays.length > 0) {
            const isDisabledInWeekDays = disableWeekdays.find((weekDay: any) => getWeekdayIndex(weekDay) === dn);
            if (isDisabledInWeekDays) {
                return true;
            }
        }

        if (disableDates.length > 0) {
            const isDisabledInDays = disableDates.find((DateObject: DateObject) =>
                (DateObject.year === 0 || DateObject.year === date.year) &&
                (DateObject.month === 0 || DateObject.month === date.month) && DateObject.day === date.day);
            if (isDisabledInDays) {
                return true;
            }
        }

        if (disablePeriod.length > 0) {
            const isDisabledInRange = disablePeriod.find((period: Period) => isInitializedDate(period.from) &&
                isInitializedDate(period.to) && dateMs >= getTimeInMilliseconds(period.from) && dateMs <= getTimeInMilliseconds(period.to));
            if (isDisabledInRange) {
                return true;
            }
        }
        return false;
    }

    return { isDisabledDate };
}
